home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / docs / misc / ConcNews.lha / news / amiga.compilers / comp.sys.amiga.programmer_10841_000033.msg < prev    next >
Encoding:
Text File  |  1994-11-27  |  5.7 KB  |  121 lines

  1. Newsgroups: comp.sys.amiga.programmer
  2. Path: dd.chalmers.se!news.chalmers.se!sunic!trane.uninett.no!eunet.no!nuug!EU.net!howland.reston.ans.net!usenet.ins.cwru.edu!eff!news.duke.edu!concert!sas!mozart.unx.sas.com!walker
  3. From: walker@twix.unx.sas.com (Doug Walker)
  4. Subject: Re: Help - Boopsi
  5. Originator: walker@twix.unx.sas.com
  6. Sender: news@unx.sas.com (Noter of Newsworthy Events)
  7. Message-ID: <CpwKKB.D6B@unx.sas.com>
  8. Date: Mon, 16 May 1994 16:02:35 GMT
  9. References:  <44798@mindlink.bc.ca>
  10. Nntp-Posting-Host: twix.unx.sas.com
  11. Organization: SAS Institute Inc.
  12. Lines: 108
  13.  
  14.  
  15. In article <44798@mindlink.bc.ca>, Dave_Thomas@mindlink.bc.ca (Dave Thomas) writes:
  16. |> I was having exactly the same problem.  When I read this message, I got so
  17. |> excited I just had to log-off and try it, and, lo & behold, it worked!
  18. |> Now, the next question is, can anyone explain this to me?  Tell me if this
  19. |> is what's happening:  whenever the dispatcher is called, the program is
  20. |> saving variables, addresses, etc. on the stack, and since the dispatcher is
  21. |> called quite often, the program runs out of stack space.  If this is the
  22. |> case, and we're turning off stack checking, isn't the program going to
  23. |> write past the end of the stack and corrupt some other part of memory?  Is
  24. |> this safe?
  25. |> 
  26. |> Thanks for your help!
  27.  
  28. OK, here's a general discussion of stacks, stack checking, and
  29. callback routines, since I've answered similar questions frequently
  30. in the past couple of months.  Note that the discussion applies to
  31. BOOPSI callbacks, software interrupts, input event handlers, shared
  32. libraries, and lots of other callback-type situations.
  33.  
  34. As functions get called, they require space for local variables,
  35. parameters, and compiler work space.  The amount needed varies
  36. for different function, but it's always the same for the same
  37. function: i.e. if you call function foo() four times, the amount
  38. of stack needed is the same for each call.
  39.  
  40. When functions return, all the stack space they use is made
  41. available for other functions to use.  After the return(),
  42. the function isn't using any stack.  Therefore, it doesn't
  43. matter how many times the dispatcher is called - it will never
  44. use any more stack than the first time, assuming it doesn't
  45. call itself recursively.
  46.  
  47. One more thing to note: each task in the Amiga OS has its own stack.
  48. When BOOPSI calls your function, it calls your code from BOOPSI's task
  49. context; this means that your function is using BOOPSI's stack during
  50. that call.  This becomes important when you realize how stack checking
  51. works.
  52.  
  53. How Stack Checking Works:
  54.  
  55.    When the program starts up, the startup code (c.o or equivalent) 
  56.    makes a note of the lowest valid address in the stack.  The stack 
  57.    pointer is set to a value in the high end of the stack, and gets 
  58.    smaller as more data is added.
  59.  
  60.    At the beginning of each function, the compiler generates code to 
  61.    compare the current stack pointer with the minimum stack location
  62.    that the startup code stored.  If the difference is smaller than
  63.    the amount of stack required for the current function, it aborts the
  64.    program.  (If you're using stack EXTENSION instead of stack CHECKING,
  65.    it actually allocates a new stack for you instead of aborting.)
  66.  
  67. Now, putting two and two together, we see that stack checking will only
  68. work for one task's stack.  Why?  Because we're assuming that we know
  69. the correct minimum stack value.  Since BOOPSI calls you on BOOPSI's 
  70. stack, we don't know this correct value, and there is no way that stack
  71. checking (or stack extension) can work!
  72.  
  73. You mention that your dispatcher stores values on the stack, so you're
  74. worried that stack checking is necessary.  As long as you make sure
  75. that your function doesn't allocate very much stack (a couple of 
  76. hundred bytes at most) then you will be OK.  Your function will 
  77. allocate stack for all AUTOMATIC variables and function parameters.
  78. Static and extern variables are fine.
  79.  
  80. Speaking of static and extern variables, there is one other gotcha with
  81. callbacks: the near data register.
  82.  
  83. Register A4 is usually set up by the compiler to point to your global
  84. data.  The compiler generates code to access the global data relative
  85. to register A4 instead of at an absolute memory address.  There are 
  86. several advantages to this, including smaller code, faster code, and
  87. reentrant code (code that can be part of several processes at the
  88. same time.)
  89.  
  90. When BOOPSI calls your callback function, it does not set up register
  91. A4 for you.  You have to make sure it is set up if you want to use it.
  92. There are many solutions to this problem, including the following:
  93.  
  94.    1. If you don't care about using near data, compile with DATA=FAR.
  95.       This will eliminate the use of register A4 for global data.
  96.       
  97.    2. If your program was not linked with cres.o, declare your BOOPSI
  98.       callback with the __saveds keyword.  This will force the compiler
  99.       to generate code to load A4 at the start of the function.  This
  100.       will not work from cres.o programs.
  101.  
  102.    3. From cres.o programs, pass the correct A4 value as your UserData
  103.       parameter.  Get its value with the "getreg()" function (defined 
  104.       in <dos.h>):
  105.  
  106.          long UserData = getreg(REG_A4);
  107.  
  108.       once you receive it in your callback, put it with putreg:
  109.  
  110.          putreg(REG_A4, UserData);
  111.  
  112. Note that "string literals" are also global data, so you may need 
  113. global data in places that you don't think you do...
  114. -- 
  115.   *****                    / walker@unx.sas.com
  116.  *|_o_o|\\     Doug Walker<  BIX, Portal: djwalker
  117.  *|. o.| ||                \ CompuServe: 71165,2274
  118.   | o  |//     
  119.   ====== 
  120. Any opinions expressed are mine, not those of SAS Institute, Inc.
  121.